package sjg.DataStructures.sort;

import sjg.DataStructures.util.SortUtils;

/**
 * 快速排序 —— 快排
 * 从小到大排序 - 使用递归
 */
public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {-9, 889, 98, 3, 24, 125, 213, 5};
        System.out.println("排序前原数组打印：");
        SortUtils.print(arr);
        quickSort(arr, 0, arr.length - 1);
        System.out.println("排序后原数组打印：");
        SortUtils.print(arr);
    }

    // 快排 —— 使用递归
    private static void quickSort(int[] arr, int left, int right) {
        int l = left; // 左下标
        int r = right; // 右下标
        // pivot 中轴值
        int pivot = arr[(left + right) / 2];

        int temp = 0;// 临时变量
        // while循环的目的是让比pivot值小的放到左边，比pivot大的值放右边
        while (l < r) {
            // 在privot的左边一直找，找到大于等于pivot值，才退出
            while (arr[l] < pivot) {
                l += 1;
            }
            // 在pivot的右边一直找，找到小于等于pivot值，才退出
            while (arr[r] > pivot) {
                r -= 1;
            }
            // 如果l>=r, 说民pivot的左右两边值，已经按照左边全部小于pivot值，右边全部大于pivot值。
            if (l >= r) {
                break;
            }

            // 交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            // 如果交换后，发现这个arr[l]==pivot, r--, 前移
            if (arr[l] == pivot) {
                r -= l;
            }
            // 如果交换后，发现这个arr[r]==pivot,l++, 后移
            if (arr[r] == pivot) {
                l += 1;
            }
        }

        // 如果 r==l, 必须l++, 否则会栈溢出。
        if (r == l) {
            l += 1;
            r -= 1;
        }

        // 向左递归
        if (left < r) {
            quickSort(arr, left, r);
        }
        if (right > l) {
            quickSort(arr, l, right);
        }

    }
}
